home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / Z4Z4FILE.CPP < prev    next >
C/C++ Source or Header  |  1995-09-19  |  12KB  |  389 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    z4z4file.cpp
  5. //   Title:    ZIP+4 Engine
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //    This module contains code for the class Z4_Z4_FILE.
  24. //
  25. //    The code in this module may be written in C++ or C.
  26. //
  27. //    This module is portable to:
  28. //        DOS 3.X+
  29. //        MS Windows 3.X+
  30. //        OS/2 2.X+
  31. //        OS/2 2.0 PM
  32. //
  33. //    The following compilers are supported:
  34. //        MSC 6.0A
  35. //        MSC/C++ 7.0
  36. //        Borland C++ 3.1 for DOS
  37. //        Borland C++ 1.0 for OS/2 2.X
  38. //
  39. //----------------------------------------------------------------------------
  40. #include <z4.h>
  41.  
  42.  
  43. //----------------------------------------------------------------------------
  44. //    Globals
  45. //----------------------------------------------------------------------------
  46. PCSZ Z4_Z4_FILE::pcszLogical = "ZIP4";
  47.  
  48.  
  49. //----------------------------------------------------------------------------
  50. //   Description:    Default constructor
  51. //    Parameters:
  52. //       Returns:    
  53. //----------------------------------------------------------------------------
  54. FN_M Z4_Z4_FILE::Z4_Z4_FILE()
  55. {
  56.     Z4_Z4_FILE::Initialize(CL_INIT_CLASS);
  57. }
  58.  
  59.  
  60. //----------------------------------------------------------------------------
  61. //   Description:    Copy constructor
  62. //    Parameters:    rcz4_z4_file        Reference to object to copy.
  63. //       Returns:    
  64. //----------------------------------------------------------------------------
  65. FN_M Z4_Z4_FILE::Z4_Z4_FILE(RCZ4_Z4_FILE rcz4_z4_file)
  66. {
  67.     Z4_Z4_FILE::Initialize(CL_INIT_CLASS);
  68.     *this = rcz4_z4_file;
  69. }
  70.  
  71.  
  72. //----------------------------------------------------------------------------
  73. //   Description:    Destructor
  74. //    Parameters:
  75. //       Returns:    
  76. //----------------------------------------------------------------------------
  77. FN_M Z4_Z4_FILE::~Z4_Z4_FILE()
  78. {
  79.     Z4_Z4_FILE::Destroy(FALSE);
  80. }
  81.  
  82. //----------------------------------------------------------------------------
  83. //   Description:    Destroy object. Free any resources used by object.
  84. //                          Normally called by destructor.
  85. //                        Should allow multiple calls from various classes.
  86. //    Parameters:    fDestroyAll        Destroy parents also?
  87. //                                            Default is TRUE.
  88. //       Returns:    TRUE if successful.
  89. //----------------------------------------------------------------------------
  90. BOOL FN_M Z4_Z4_FILE::Destroy(BOOL fDestroyAll)
  91. {
  92.     DioCloseLogical(hlf);
  93.     DioCloseLogical(hlfRecNo);
  94.     Z4Z4ExpandTerminate(&z4_z4_blk);
  95.     Z4_Z4_FILE::Initialize(CL_INIT_CLASS_VARS);
  96.     if (fDestroyAll)                            // Destroy parent.
  97.         Z4_Z4_FILE_PARENT::Destroy(fDestroyAll);                    
  98.     return TRUE;
  99. }
  100.  
  101.  
  102. //----------------------------------------------------------------------------
  103. //   Description:    Find first record in a specified block.
  104. //    Parameters:    z4_z4            Buffer for record
  105. //                        pcszFinance    Finance number to search
  106. //                        pcszPriName    Primary name to search
  107. //                        pcszPriNo    Primary number to search
  108. //       Returns:    TRUE if valid
  109. //----------------------------------------------------------------------------
  110. BOOL FN_M Z4_Z4_FILE::First(RZ4_Z4 rz4_z4, PCSZ pcszFinance, PCSZ pcszPriName, PCSZ pcszPriNo)
  111. {
  112.     if (IsError())                                // Check error condition
  113.         return FALSE;
  114.  
  115.     BYTE bKey[MAX_Z4_KEY];
  116.     Z4Z4Key(bKey, pcszFinance, pcszPriName, pcszPriNo);
  117.  
  118.     LONG lIndexBlock;
  119.     if (!DioReadIndex(hlf, bKey, sizeof(bKey), &lIndexBlock))
  120.         return SetError();
  121.  
  122.     if (First(rz4_z4, lIndexBlock))
  123.         {
  124.         do
  125.             {
  126.             BYTE bKey2[MAX_Z4_KEY];
  127.             Z4Z4Key(bKey2, rz4_z4.szFinance, rz4_z4.szPriName, rz4_z4.szPriLo);
  128.             if (memcmp(bKey2, bKey, MAX_Z4_KEY) >= 0)
  129.                 return TRUE;
  130.             }
  131.         while (Next(rz4_z4));
  132.         return !IsError();
  133.         }
  134.     return FALSE;
  135. }
  136.  
  137.  
  138. //----------------------------------------------------------------------------
  139. //   Description:    Find first record in a specified block.
  140. //    Parameters:    z4_z4            Buffer for record
  141. //                        _lBlock        Block to read
  142. //                                        Default is 0.
  143. //       Returns:    TRUE if valid
  144. //----------------------------------------------------------------------------
  145. BOOL FN_M Z4_Z4_FILE::First(RZ4_Z4 rz4_z4, LONG _lBlock)
  146. {
  147.     if (IsError())                                // Check error condition
  148.         return FALSE;
  149.  
  150.     if (_lBlock >= lBlocks)                    // End of file!
  151.         return FALSE;
  152.  
  153.     if (!fBlock || lBlock != _lBlock)
  154.         {
  155.         lBlock = _lBlock;
  156.         fBlock = TRUE;
  157.         fOffset = FALSE;
  158.         if (!DioSeekBlock(hlf, lBlock)
  159.         || !DioReadBlock(hlf, NULL, &pb, NULL)
  160.         || !Z4Z4ExpandReset(&z4_z4_blk, pb, (SIZET)usBlockSize))
  161.             return SetError();
  162.         }
  163.     if (fOffset && usOffset == 0)
  164.         {
  165.         rz4_z4 = z4_z4_blk.z4;                // Record was the existing expanded
  166.         return TRUE;                            //  record
  167.         }
  168.     if (fOffset)                                // Reset expander for current block
  169.         if (!Z4Z4ExpandReset(&z4_z4_blk, pb, (SIZET)usBlockSize))
  170.             return SetError();
  171.                                                     // Expand first record
  172.     if (!Z4Z4Expand(&z4_z4_blk, &rz4_z4))
  173.         return SetError();
  174.     fOffset = TRUE;
  175.     usOffset = 0;
  176.     rz4_z4.recid.lBlock = lBlock;
  177.     rz4_z4.recid.usOffset = usOffset;
  178.     return TRUE;
  179. }
  180.  
  181.  
  182. //----------------------------------------------------------------------------
  183. //   Description:    Initialize object. 
  184. //                          Normally called by constructor.
  185. //                        Should allow multiple calls from various classes.
  186. //    Parameters:    sInit        Initialization code. May be one of the following:
  187. //                                        CL_INIT_CLASS            Reset class variables and
  188. //                                                                    and dynamic allocations for
  189. //                                                                    this class only.
  190. //                                        CL_INIT_CLASS_VARS    Reset class variables for
  191. //                                                                    this class only.
  192. //                                        CL_INIT_VARS            Reset class variables for
  193. //                                                                    this class only.
  194. //                                        CL_INIT_ALL                Initialize class and all 
  195. //                                                                    parent class, including
  196. //                                                                    dynamic memory allocation.
  197. //                                    Default is CL_INIT_ALL
  198. //       Returns:    TRUE if successful.
  199. //----------------------------------------------------------------------------
  200. BOOL FN_M Z4_Z4_FILE::Initialize(SHORT sInit)
  201. {
  202.     if (sInit == CL_INIT_VARS || sInit == CL_INIT_ALL)
  203.         Z4_Z4_FILE_PARENT::Initialize(sInit);
  204.  
  205.     hlf = -1;
  206.     hlfRecNo = -1;
  207.     lRecs = -1;
  208.     memset(&z4_z4_blk, 0, sizeof(z4_z4_blk));
  209.     fBlock = FALSE;
  210.     fOffset = FALSE;
  211.     return TRUE;
  212. }
  213.  
  214.  
  215. //----------------------------------------------------------------------------
  216. //   Description:    Check if object is in error state.
  217. //                          IsValid() && IsError() MUST NOT BE DEPENDENT ON ONE ANOTHER.
  218. //    Parameters:
  219. //       Returns:    TRUE if in error state.
  220. //----------------------------------------------------------------------------
  221. BOOL FN_M Z4_Z4_FILE::IsError() const
  222. {
  223.     return Z4_Z4_FILE_PARENT::IsError()
  224.         || DioIsError(hlf)
  225.         || DioIsError(hlfRecNo);
  226. }
  227.  
  228.  
  229. //----------------------------------------------------------------------------
  230. //   Description:    Check if object is valid
  231. //                          IsValid() && IsError() MUST NOT BE DEPENDENT ON ONE ANOTHER.
  232. //    Parameters:
  233. //       Returns:    TRUE if valid
  234. //----------------------------------------------------------------------------
  235. BOOL FN_M Z4_Z4_FILE::IsValid() const
  236. {
  237.     return Z4_Z4_FILE_PARENT::IsValid()
  238.         && DioIsValid(hlf)
  239.         && DioIsValid(hlfRecNo);
  240. }
  241.  
  242.  
  243. //----------------------------------------------------------------------------
  244. //   Description:    Read next record
  245. //    Parameters:    z4_z4        Buffer for record
  246. //       Returns:    TRUE if record found. FALSE if at end of file.
  247. //----------------------------------------------------------------------------
  248. BOOL FN_M Z4_Z4_FILE::Next(RZ4_Z4 rz4_z4)
  249. {
  250.     if (IsError())                                // Check error condition
  251.         return FALSE;
  252.     Assert(fBlock && fOffset);
  253.                                                     // Expand next record or goto next block
  254.     if (!Z4Z4Expand(&z4_z4_blk, &rz4_z4))
  255.         return First(rz4_z4, lBlock + 1);
  256.     usOffset++;
  257.     rz4_z4.recid.lBlock = lBlock;
  258.     rz4_z4.recid.usOffset = usOffset;
  259.     return TRUE;
  260. }
  261.  
  262.  
  263. //----------------------------------------------------------------------------
  264. //   Description:    Open Z4 file
  265. //    Parameters:
  266. //       Returns:    TRUE if valid
  267. //----------------------------------------------------------------------------
  268. BOOL FN_M Z4_Z4_FILE::Open()
  269. {
  270.         if (!Z4_INQ::Start()
  271.         || !DioOpenIndex(pcszLogical, &hlf)
  272.     || !DioCacheSet(hlf, 1)
  273.     || !DioGetRecords(hlf, &lRecs)
  274.     || !DioGetBlockSize(hlf, &usBlockSize)
  275.     || !DioGetBlocks(hlf, &lBlocks)
  276.     || !DioOpenRecNo(pcszLogical, &hlfRecNo)
  277.     || !Z4Z4ExpandInitialize(&z4_z4_blk))
  278.         return SetError();
  279.  
  280.     return TRUE;
  281. }
  282.  
  283.  
  284. //----------------------------------------------------------------------------
  285. //   Description:    Assignment operator
  286. //                          NOTE: Don't copy object into self
  287. //    Parameters:    rcz4_z4_file        Reference to right value.
  288. //       Returns:    Reference to new object.
  289. //----------------------------------------------------------------------------
  290. RCZ4_Z4_FILE FN_M Z4_Z4_FILE::operator=(RCZ4_Z4_FILE rcz4_z4_file)
  291. {
  292.     if (this != &rcz4_z4_file)
  293.         {
  294.         Invalid("Z4_Z4_FILE::operator=");
  295.         }
  296.     return (RCZ4_Z4_FILE)*this;
  297. }
  298.  
  299.  
  300. //----------------------------------------------------------------------------
  301. //   Description:    Read a particular record from the file
  302. //    Parameters:    z4_z4            Buffer for record
  303. //                        lRec            Record to read.
  304. //                                        If < 0, return current record
  305. //                                        Default is -1.
  306. //       Returns:    TRUE if record found. FALSE if at end of file.
  307. //----------------------------------------------------------------------------
  308. BOOL FN_M Z4_Z4_FILE::Record(RZ4_Z4 rz4_z4, LONG lRec)
  309. {
  310.     RECID recid;
  311.  
  312.     if (IsError())                                // Check error condition
  313.         return FALSE;
  314.     if (lRec >= lRecs)
  315.         return FALSE;
  316.     if (lRec < 0)                                // Return current record 
  317.         {
  318.         if (fBlock && fOffset)
  319.             {
  320.             rz4_z4 = z4_z4_blk.z4;                
  321.             return TRUE;
  322.             }
  323.         return FALSE;
  324.         }                                            // Convert to record id
  325.     if (!DioRecNo2RecId(hlfRecNo, lRec, &recid))
  326.         return SetError();
  327.  
  328.     return Record(rz4_z4, recid);
  329. }
  330.  
  331.  
  332. //----------------------------------------------------------------------------
  333. //   Description:    Read a particular record from the file by record id
  334. //    Parameters:    z4_z4            Buffer for record
  335. //                        recid            Record id to read.
  336. //       Returns:    TRUE if record found. FALSE if at end of file.
  337. //----------------------------------------------------------------------------
  338. BOOL FN_M Z4_Z4_FILE::Record(RZ4_Z4 rz4_z4, RECID recid)
  339. {
  340.     if (IsError())                                // Check error condition
  341.         return FALSE;
  342.                                                     // Move to correct block
  343.     if (!fBlock || recid.lBlock != lBlock)
  344.         if (!First(rz4_z4, recid.lBlock))
  345.             return FALSE;
  346.     if (recid.usOffset < usOffset)        // If past desired record, restart 
  347.         {                                            //  from offset 0
  348.         if (!Z4Z4ExpandReset(&z4_z4_blk, pb, (SIZET)usBlockSize)
  349.         || !Z4Z4Expand(&z4_z4_blk, &rz4_z4))
  350.             return SetError();
  351.  
  352.         usOffset = 0;
  353.         fOffset = TRUE;
  354.         }                        
  355.     rz4_z4 = z4_z4_blk.z4;                // Search for desired record
  356.     for (; usOffset < recid.usOffset; usOffset++)
  357.         if (!Z4Z4Expand(&z4_z4_blk, &rz4_z4))
  358.             return SetError();
  359.     rz4_z4.recid.lBlock = lBlock;
  360.     rz4_z4.recid.usOffset = usOffset;
  361.     return TRUE;
  362. }
  363.  
  364.  
  365. //----------------------------------------------------------------------------
  366. //   Description:    
  367. //    Parameters:    
  368. //       Returns:    Record number of current record or -1
  369. //----------------------------------------------------------------------------
  370. LONG FN_M Z4_Z4_FILE::RecordNo()
  371. {
  372.     if (IsError())                                // Check error condition
  373.         return -1;
  374.     RECID recid;
  375.     recid.usOffset = usOffset;
  376.     recid.lBlock = lBlock;
  377.     LONG lRec;
  378.     if (!DioRecId2RecNo(hlfRecNo, &lRec, &recid))
  379.         {
  380.         SetError();
  381.         return -1;
  382.         }
  383.     return lRec;
  384.  
  385. }
  386. //----------------------------------------------------------------------------
  387. //------------------------------- End of File --------------------------------
  388. //----------------------------------------------------------------------------
  389.